/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package nnet2.gui;

import java.awt.Color;
import java.awt.ComponentOrientation;
import java.awt.Dimension;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;

/**
 *
 * @author kalinskia
 */
public class OnLineLearningPlotPanel extends JPanel{
    private ArrayList<Double> expected = new ArrayList<Double>();
    private ArrayList<Double> prediction = new ArrayList<Double>();
    private ArrayList<Double> errLog = new ArrayList<Double>();
    private int iteration = 0;
    private double error = Double.NaN;
    private double mse = Double.NaN;

    public OnLineLearningPlotPanel(){
        this.setPreferredSize(new Dimension(800, 300));

    }

    @Override
    protected void paintComponent(Graphics g) {
        int len = this.expected.size();
        if(len > this.getWidth()) {
            this.setSize(len,this.getHeight());
            this.setPreferredSize(new Dimension(len,this.getHeight()));
            this.setBounds(0, 0, len, this.getHeight());
        }
        int step = this.getWidth()/len;

        g.setColor(Color.white);
        g.fillRect(0, 0, this.getWidth(), this.getHeight());

        g.setColor(Color.BLUE);
        if(this.iteration > -1) g.drawString(String.format("Iteration: %d", this.iteration), 10, 10);
        if(this.error != Double.NaN) g.drawString(String.format("Error: %f", this.error), 10, 20);
        if(this.getMse() != Double.NaN) g.drawString(String.format("MSE: %f", this.mse), 10, 30);

        g.setColor(Color.DARK_GRAY);
        g.drawLine(0, this.getHeight()>>1, this.getWidth(), this.getHeight()>>1);
        g.setColor(Color.LIGHT_GRAY);
        g.drawLine(0, this.getHeight()>>2, this.getWidth(), this.getHeight()>>2);
        g.drawLine(0, 3 * this.getHeight()>>2, this.getWidth(), 3 * this.getHeight()>>2);

        for(int i = 0; i < this.expected.size() - 1;i++){
            g.setColor(Color.BLACK);
            int x = i * step;
            int x2 = x + step;
            g.fillRect(x-1, getExpected(i)-1,3, 3);
            g.drawLine(x, getExpected(i), x2, getExpected(i+1));
            g.setColor(Color.RED);
            g.drawLine(x, getPredicted(i), x2, getPredicted(i+1));
            g.fillRect(x-1, getPredicted(i)-1, 3, 3);
        }
    }

    private int getPredicted(int i) {
        return this.getHeight() - ((int) (this.prediction.get(i) * this.getHeight() / 2) + this.getHeight() / 2);
    }

    private int getExpected(int i) {
        return this.getHeight() - ((int) (this.expected.get(i) * this.getHeight() / 2) + this.getHeight() / 2);
    }

    public void nextPrediction(double exp, double pred, double err){
        iteration++;
        this.expected.add(exp);
        this.prediction.add(pred);
        this.error=err;
        this.errLog.add(err);
//        try {
//            Thread.sleep(50);
//        } catch (InterruptedException ex) {
//            Logger.getLogger(OnLineLearningPlotPanel.class.getName()).log(Level.SEVERE, null, ex);
//        }
        this.repaint();
    }

    public static OnLineLearningPlotPanel showPlot(){
        JFrame f = new JFrame();
        final OnLineLearningPlotPanel plotPanel = new OnLineLearningPlotPanel();
        JScrollPane scroll = new JScrollPane(plotPanel);
        scroll.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
        scroll.setAutoscrolls(true);
        f.setContentPane(scroll);
        f.setSize(800, 300);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setDefaultLookAndFeelDecorated(true);

        //f.pack();
        f.setVisible(true);
        return plotPanel;
    }

    /**
     * @return the mse
     */
    public double getMse() {
        return mse;
    }

    /**
     * @param mse the mse to set
     */
    public void setMse(double mse) {
        this.mse = mse;
    }
}
